package com.htl.exampro.exam.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.htl.exampro.base.model.PageResult;
import com.htl.exampro.base.model.ServerResponse;
import com.htl.exampro.base.utils.UserUtil;
import com.htl.exampro.exam.mapper.ExamMapper;
import com.htl.exampro.exam.mapper.ExamResultMapper;
import com.htl.exampro.exam.pojo.constant.ExamStatusConstant;
import com.htl.exampro.exam.pojo.domain.ExamDO;
import com.htl.exampro.exam.pojo.domain.ExamResultDO;
import com.htl.exampro.exam.pojo.query.ExamPageParam;
import com.htl.exampro.exam.pojo.vo.ExamVO;
import com.htl.exampro.exam.service.ExamService;
import com.htl.exampro.paper.api.PaperApi;
import com.htl.exampro.paper.pojo.vo.PaperQuestionVO;
import com.htl.exampro.paper.pojo.vo.PaperVO;
import com.htl.exampro.exam.service.ExamResultService;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.HashMap;

/**
 * 考试服务实现类
 */
@Service
public class ExamServiceImpl extends ServiceImpl<ExamMapper, ExamDO> implements ExamService {

    @Autowired
    private PaperApi paperApi;

    @Resource
    private ExamResultMapper examResultMapper;

    @Autowired
    private ExamResultService examResultService;

    @Override
    public PageResult<ExamVO> getExamPage(ExamPageParam pageParam) {
        Page<ExamDO> page = new Page<>(pageParam.getPageNumber(), pageParam.getPageSize());
        LambdaQueryWrapper<ExamDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ExamDO::getCreatedPerson, UserUtil.getUserId());
        wrapper.like(StringUtils.isNotBlank(pageParam.getExamName()), ExamDO::getExamName, pageParam.getExamName());
        wrapper.orderByDesc(ExamDO::getEndTime);
        page(page, wrapper);
        PageResult<ExamVO> result = PageResult.result(page, ExamVO.class);
        List<String> examIds = result.getData().stream().map(ExamVO::getExamId).toList();
        if (examIds.isEmpty())
            return result;
        LambdaQueryWrapper<ExamResultDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(ExamResultDO::getExamId, examIds);
        queryWrapper.eq(ExamResultDO::getUserId, UserUtil.getUserId());
        List<ExamResultDO> examResultDOS = examResultMapper.selectList(queryWrapper);
        Map<Long, ExamResultDO> resultDOMap = examResultDOS.stream()
                .collect(Collectors.toMap(ExamResultDO::getExamId, o -> o));
        for (ExamVO examVO : result.getData()) {
            ExamResultDO resultDO = resultDOMap.get(Long.parseLong(examVO.getExamId()));
            if (resultDO == null) {
                examVO.setStatusId(ExamStatusConstant.WBM.getStatusId());
            } else
                examVO.setStatusId(resultDO.getStatusId());
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createExam(ExamVO examVO) {
        LocalDateTime startTime = examVO.getStartTime();
        LocalDateTime endTime = examVO.getEndTime();
        // 计算时间差（分钟）
        long minutesDiff = Duration.between(startTime, endTime).toMinutes();
        examVO.setDuration((int) minutesDiff);
        save(BeanUtil.toBean(examVO, ExamDO.class));
    }

    @Override
    public ExamVO getExam(Long id) {
        return BeanUtil.toBean(getById(id), ExamVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateExam(ExamVO exam) {
        updateById(BeanUtil.toBean(exam, ExamDO.class));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteExam(String id) {
        removeById(id);
    }

    @Override
    public Map<String, Object> getExamInfo(String examId) {
        ExamDO examDO = getById(examId);
        ExamVO examVO = BeanUtil.toBean(examDO, ExamVO.class);
        LocalDateTime endTime = examVO.getEndTime();
        long end = endTime.atZone(ZoneId.systemDefault())
                .toInstant()
                .toEpochMilli();
        long now = System.currentTimeMillis();

        ServerResponse<PaperVO> response = paperApi.queryPaperById(examVO.getPaperId());
        List<PaperQuestionVO> paperQuestions = response.getResult().getPaperQuestions();

        return Map.of("examInfo", examVO, "questions", paperQuestions, "remainingTime", (end - now) / 1000);
    }
}